<html>
<head><meta charset="utf-8"><title>union field semantics and safety · t-lang · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/index.html">t-lang</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html">union field semantics and safety</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="248258084"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248258084" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248258084">(Aug 03 2021 at 18:12)</a>:</h4>
<p>Starting this thread to discuss <a href="https://github.com/rust-lang/rust/issues/87520">https://github.com/rust-lang/rust/issues/87520</a> .<br>
cc <span class="user-mention" data-user-id="255061">@Léo Lanteri Thauvin</span> <span class="user-mention" data-user-id="224471">@Lokathor</span> <span class="user-group-mention" data-user-group-id="1977">@T-lang</span> <span class="user-mention" data-user-id="120791">@RalfJ</span></p>



<a name="248258184"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248258184" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248258184">(Aug 03 2021 at 18:13)</a>:</h4>
<p>When we discussed this in today's lang meeting, we came to the conclusion that several of the "safe" examples shouldn't be safe.</p>



<a name="248258399"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248258399" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248258399">(Aug 03 2021 at 18:15)</a>:</h4>
<p>To the degree that we may potentially want to consider those reads a soundness hole and fix them (and use crater to determine how much impact that would have, hopefully fairly little given that it mostly affects irrefutable patterns).</p>



<a name="248258555"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248258555" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248258555">(Aug 03 2021 at 18:16)</a>:</h4>
<p>My first inclination would be for <em>all</em> of the patterns shown there, other than the match of <code>()</code>, to be unsafe.</p>



<a name="248258699"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248258699" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248258699">(Aug 03 2021 at 18:17)</a>:</h4>
<p>(The ZST <code>()</code> would only be safe because it's a simple special case of "every possible value of this memory is valid" semantics that we may want in the future for safe reads of the fields from <code>union { f: f32, u: u32 }</code>; for a ZST, every possible value of the zero bytes of memory they occupy is valid.)</p>



<a name="248259325"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248259325" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248259325">(Aug 03 2021 at 18:22)</a>:</h4>
<p>As far as I can tell, there wasn't any specific deliberate effort to make some union field reads safe in the MIR unsafety checker; it sounds like it just happened because of the semantics of MIR.</p>



<a name="248264508"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248264508" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248264508">(Aug 03 2021 at 19:03)</a>:</h4>
<p><span class="user-mention silent" data-user-id="239881">Josh Triplett</span> <a href="#narrow/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety/near/248258555">said</a>:</p>
<blockquote>
<p>My first inclination would be for <em>all</em> of the patterns shown there, other than the match of <code>()</code>, to be unsafe.</p>
</blockquote>
<p><span class="user-mention" data-user-id="239881">@Josh Triplett</span> I know you said similar in the meeting, but I want to clarify this point: You want to treat this as a special case based on the hypothetical generalization in the future? Why not wait until that future to support the ZST case (where it would, I assume, naturally fall out of the generalization you described)</p>



<a name="248264702"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248264702" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248264702">(Aug 03 2021 at 19:04)</a>:</h4>
<p>I guess if it reduces the impact of this change, in terms of code breakage, then that’s a motivation. But we’d have to get some data on that.</p>



<a name="248273066"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248273066" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248273066">(Aug 03 2021 at 20:05)</a>:</h4>
<p>We could say that "any read of a union is unsafe", which is a very easy rule to understand. If we stick to that, then matching on a ZST does no reads, and so is still safe, regardless of how the other situations shake out.</p>



<a name="248273746"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248273746" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Léo Lanteri Thauvin <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248273746">(Aug 03 2021 at 20:10)</a>:</h4>
<p><span class="user-mention silent" data-user-id="224471">Lokathor</span> <a href="#narrow/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety/near/248273066">said</a>:</p>
<blockquote>
<p>We could say that "any read of a union is unsafe", which is a very easy rule to understand. If we stick to that, then matching on a ZST does no reads, and so is still safe, regardless of how the other situations shake out.</p>
</blockquote>
<p>I think this is roughly how the unsafety checker works today: the reason why it doesn't report a read of a union field is because they are absent in MIR</p>



<a name="248273848"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248273848" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Léo Lanteri Thauvin <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248273848">(Aug 03 2021 at 20:11)</a>:</h4>
<p>And it still leads to behavior that is arguably surprising</p>



<a name="248274825"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248274825" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248274825">(Aug 03 2021 at 20:18)</a>:</h4>
<p>The only reason to support the ZST case would be because it's already supported today and it might avoid some breakage. If crater shows that it doesn't matter either way, then I have no problem with the simpler rule of all field reads being unsafe, until we have a fuller infrastructure for determining what's safe.</p>



<a name="248274892"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248274892" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248274892">(Aug 03 2021 at 20:19)</a>:</h4>
<p>But the weirdness of the ZST case is also why I think it's unlikely to arise in practice, so it may not matter either way.</p>



<a name="248275579"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248275579" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248275579">(Aug 03 2021 at 20:24)</a>:</h4>
<p><span class="user-mention silent" data-user-id="255061">Léo Lanteri Thauvin</span> <a href="#narrow/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety/near/248273746">said</a>:</p>
<blockquote>
<p>I think this is roughly how the unsafety checker works today: the reason why it doesn't report a read of a union field is because they are absent in MIR</p>
</blockquote>
<p>But it appears that in today's rust the <code>OneVal::One</code> situation is also skipping the read.</p>
<p>And while it's easy to see that this is in some sense technically correct: It's UB to have read any value other than the one enum variant that exists, so you can naturally skip the read, I think that maybe should stay unsafe anyway.</p>



<a name="248275713"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248275713" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248275713">(Aug 03 2021 at 20:25)</a>:</h4>
<p>Even if the read doesn't actually occur after optimization, act "as if" it did occur and make it require unsafe.</p>



<a name="248328999"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248328999" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248328999">(Aug 04 2021 at 09:41)</a>:</h4>
<blockquote>
<p>safe reads of the fields from union { f: f32, u: u32 }</p>
</blockquote>
<p>FWIW, this would imply that <code>MaybeUninit::&lt;u32&gt;::uninit().assume_init()</code> is not UB. But we don't have to agree on this now I guess. ;)</p>



<a name="248329135"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248329135" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248329135">(Aug 04 2021 at 09:43)</a>:</h4>
<p><span class="user-mention silent" data-user-id="224471">Lokathor</span> <a href="#narrow/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety/near/248275713">said</a>:</p>
<blockquote>
<p>Even if the read doesn't actually occur after optimization, act "as if" it did occur and make it require unsafe.</p>
</blockquote>
<p>I think <span class="user-mention" data-user-id="239881">@Josh Triplett</span> has been using <code>read</code> to mean the syntactic occurrence of a field access in the code, not an actual load being emitted in the LLVM IR.</p>



<a name="248329164"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248329164" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248329164">(Aug 04 2021 at 09:43)</a>:</h4>
<p>I dont have a strong opinion on this as long as we dont presuppose that reading <code>i32</code> fields might ever be safe.</p>



<a name="248342088"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248342088" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248342088">(Aug 04 2021 at 12:21)</a>:</h4>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> <a href="#narrow/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety/near/248328999">said</a>:</p>
<blockquote>
<blockquote>
<p>safe reads of the fields from union { f: f32, u: u32 }</p>
</blockquote>
<p>FWIW, this would imply that <code>MaybeUninit::&lt;u32&gt;::uninit().assume_init()</code> is not UB. But we don't have to agree on this now I guess. ;)</p>
</blockquote>
<p>Can I ask the reasoning that leads to that implication? I think Josh's example is dependent on the structure of the union in question. In particular, a <code>MaybeUninit</code> has fields with differing sizes (<code>()</code> and <code>T</code>), so its possible to create it via the <code>MaybeUninit { uninit: () }</code> form and thus one cannot assume there are initialized bits for the <code>T</code>. I thought the point of <span class="user-mention" data-user-id="239881">@Josh Triplett</span> ’s example was that no matter what path you use to create a <code>union { f: f32, u: u32 }</code>, you have to provide the 32-bits of data (that is, assuming only safe code here).</p>



<a name="248342789"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248342789" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248342789">(Aug 04 2021 at 12:29)</a>:</h4>
<p>Josh said the justification is "every possible value of this memory is valid". But I don't think that uninitialized memory (which is distinct from any fixed, initialized bit pattern) should be valid for for integers.</p>



<a name="248342815"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248342815" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248342815">(Aug 04 2021 at 12:29)</a>:</h4>
<p>but maybe I misunderstood</p>



<a name="248342828"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248342828" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248342828">(Aug 04 2021 at 12:29)</a>:</h4>
<p>At least currently, that's not how validity of unions works in the formal model. A union is always an arbitrary blob of bytes of the appropriate size, regardless of the types in the union. I think even a singleton union <code>union { u: u32 }</code> is equivalent to <code>MaybeUninit&lt;u32&gt;</code> by this model.</p>
<p>I agree that this is a little surprising, but I think it is simpler for the compiler since there isn't much advantage in exploiting an invariant like that</p>



<a name="248342838"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248342838" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248342838">(Aug 04 2021 at 12:29)</a>:</h4>
<p>I would assume that detecting whether that copy is safe is along the lines of safe transmute, though, otherwise you'd have to be incredibly choosy about which types work (which would probably mean that all fields are scalar types of the same size is the best you can do).</p>



<a name="248342951"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248342951" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248342951">(Aug 04 2021 at 12:30)</a>:</h4>
<p>also this pertains to the validity invariant for <code>union</code> -- if it's up to me, then <code>MaybeUninit::uninit().assume_init()</code> will actually be non-UB for <em>any union</em>. (It might still be <code>unsafe</code> because unions can have user-defined safety invariants like all other named types.)<br>
(EDIT: ah, raced with <span class="user-mention" data-user-id="271719">@Mario Carneiro</span> )</p>



<a name="248343381"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248343381" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248343381">(Aug 04 2021 at 12:34)</a>:</h4>
<p>Couldn't it still be safe, though, if all unions obtained a safety invariant of holding a valid value of it's elements (idk how breaking that would be, though).</p>



<a name="248343425"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248343425" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248343425">(Aug 04 2021 at 12:35)</a>:</h4>
<p>I think the complication this saves is the need to define "active element" a la C++</p>



<a name="248343463"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248343463" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248343463">(Aug 04 2021 at 12:35)</a>:</h4>
<p>Well, that wouldn't need to be defined.</p>



<a name="248343632"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248343632" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248343632">(Aug 04 2021 at 12:37)</a>:</h4>
<blockquote>
<p>It is generally valid for unsafe code to assume that at least one field of a union is valid </p>
</blockquote>
<p>would be how I'd write it</p>



<a name="248343653"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248343653" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248343653">(Aug 04 2021 at 12:37)</a>:</h4>
<p>I don't think you can guarantee that it is valid with any of the variants. For example you could have a <code>union { (bool, u8), (u8, bool) }</code> set to <code>(3, 3)</code></p>



<a name="248343898"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248343898" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248343898">(Aug 04 2021 at 12:39)</a>:</h4>
<p>I think validity checking in miri for this case would be pretty hard (under a hypothetical alternative validity invariant that says a union is valid iff it is valid at one of its variants)</p>



<a name="248344027"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248344027" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248344027">(Aug 04 2021 at 12:41)</a>:</h4>
<p>Well, that's why I'd say it's a safety invariant. This would allow it to become safe to read union fields under the same rules for safe transmute (If all fields can be transmuted to each other in the current context, assuming nothing, then it can be safe to read any field of a type with trivial destruction)</p>



<a name="248344053"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248344053" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248344053">(Aug 04 2021 at 12:41)</a>:</h4>
<p>(Assuming safe transmute ever happens, of course)</p>



<a name="248344124"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248344124" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248344124">(Aug 04 2021 at 12:42)</a>:</h4>
<p>The safety invariant for unions almost never matters because it is always overridden by a user-defined safety invariant</p>



<a name="248344356"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248344356" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248344356">(Aug 04 2021 at 12:44)</a>:</h4>
<p>But given how much you have to use unsafe around unions I think it is prudent to have it be the same as the validity invariant.</p>



<a name="248344705"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248344705" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248344705">(Aug 04 2021 at 12:47)</a>:</h4>
<p><span class="user-mention silent" data-user-id="257758">Connor Horman</span> <a href="#narrow/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety/near/248344027">said</a>:</p>
<blockquote>
<p>Well, that's why I'd say it's a safety invariant. This would allow it to become safe to read union fields under the same rules for safe transmute (If all fields can be transmuted to each other in the current context, assuming nothing, then it can be safe to read any field of a type with trivial destruction)</p>
</blockquote>
<p>This sounds like it wants to be a library, like some kind of <code>Transmutable&lt;A, B&gt;</code> wrapper around a <code>A, B</code> union. There is no need for it to be a language feature</p>



<a name="248349580"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248349580" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248349580">(Aug 04 2021 at 13:29)</a>:</h4>
<blockquote>
<p>Josh said the justification is "every possible value of this memory is valid".</p>
</blockquote>
<p>I don't wanna speak for Josh too much but I'm 99% sure they meant "every possible initialization" of this union (<code>{f32, u32}</code>) is valid data for all fields. <span class="user-mention" data-user-id="120791">@RalfJ</span></p>



<a name="248349845"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248349845" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248349845">(Aug 04 2021 at 13:31)</a>:</h4>
<p><span class="user-mention" data-user-id="271719">@Mario Carneiro</span> That "Transmutable" trait is already a library (<code>bytemuck</code>), and we're still making it a language feature (project safe transmute). Because it's better for the compiler to check it than to have some system you try and manage by hand.</p>



<a name="248350051"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248350051" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248350051">(Aug 04 2021 at 13:33)</a>:</h4>
<p>I mean that <code>Transmutable</code> would be powered by all that safe-transmute intrinsic stuff</p>



<a name="248350370"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248350370" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248350370">(Aug 04 2021 at 13:35)</a>:</h4>
<p>why would we add all that to the compiler and then not also eventually make the compiler able to detect when unions can be safely read from?</p>



<a name="248350656"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248350656" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248350656">(Aug 04 2021 at 13:37)</a>:</h4>
<p>because <code>Transmutable&lt;A, B&gt;</code> is actually adding a nontrivial safety invariant over <code>union { A, B }</code></p>



<a name="248350673"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248350673" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248350673">(Aug 04 2021 at 13:37)</a>:</h4>
<p>it's not just a type alias</p>



<a name="248350939"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248350939" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248350939">(Aug 04 2021 at 13:39)</a>:</h4>
<p>you could call it a safe wrapper function</p>



<a name="248351194"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248351194" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248351194">(Aug 04 2021 at 13:41)</a>:</h4>
<p>could you elaborate on what safety invariant is being added compared to the compiler detecting what reads are fine on its own?</p>



<a name="248354871"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248354871" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248354871">(Aug 04 2021 at 14:10)</a>:</h4>
<p>it makes it safe to read some fields from unions with public fields -- which is not justified by the validity invariant so it can only be the safety invariant</p>



<a name="248355544"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248355544" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248355544">(Aug 04 2021 at 14:15)</a>:</h4>
<p><span class="user-mention silent" data-user-id="271719">Mario Carneiro</span> <a href="#narrow/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety/near/248343653">said</a>:</p>
<blockquote>
<p>I don't think you can guarantee that it is valid with any of the variants. For example you could have a <code>union { (bool, u8), (u8, bool) }</code> set to <code>(3, 3)</code></p>
</blockquote>
<p>Oh, my. I had thought from the RFC that the safe writes had to be to whole variants of the union. I didn’t realize this was legal (but it is accepted by compiler today): </p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">union</span> <span class="nc">U</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">bu8</span>: <span class="p">(</span><span class="kt">bool</span><span class="p">,</span><span class="w"> </span><span class="kt">u8</span><span class="p">),</span><span class="w"> </span><span class="n">u8b</span>: <span class="p">(</span><span class="kt">u8</span><span class="p">,</span><span class="w"> </span><span class="kt">bool</span><span class="p">)</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
<span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">U</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">bu8</span>: <span class="p">(</span><span class="kc">true</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p">)};</span><span class="w"></span>
<span class="n">u</span><span class="p">.</span><span class="n">u8b</span><span class="p">.</span><span class="mi">0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">3</span><span class="p">;</span><span class="w"></span>
</code></pre></div>
<p>(and indeed, miri allows it too; miri only complains if you subsequently try to read the now-invalid boolean fields.)</p>



<a name="248355674"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248355674" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248355674">(Aug 04 2021 at 14:16)</a>:</h4>
<p>I don’t know how the compiler is going to be able to reason about code-generation for matches in such a scenario.</p>



<a name="248356097"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248356097" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248356097">(Aug 04 2021 at 14:19)</a>:</h4>
<p>(except to specify the exact order of operations for matches, e.g. that the reads will be emitted from left-to-right. Which was something we were not thrilled about doing in the lang team meeting…)</p>



<a name="248357102"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248357102" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248357102">(Aug 04 2021 at 14:26)</a>:</h4>
<p><span class="user-mention" data-user-id="120791">@RalfJ</span> assuming that A and B are some two specific types that one <em>can</em> transmute between then they would have to always meet each other's validity invariant already.</p>



<a name="248357501"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248357501" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248357501">(Aug 04 2021 at 14:29)</a>:</h4>
<p><span class="user-mention" data-user-id="224471">@Lokathor</span> but the union's validity invariant allows just plain uninit memory no matter the A/B (at least I think it should)</p>



<a name="248357614"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248357614" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248357614">(Aug 04 2021 at 14:30)</a>:</h4>
<p><span class="user-mention silent" data-user-id="116083">pnkfelix</span> <a href="#narrow/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety/near/248355674">said</a>:</p>
<blockquote>
<p>I don’t know how the compiler is going to be able to reason about code-generation for matches in such a scenario.</p>
</blockquote>
<p>what exactly is the problem?</p>



<a name="248357669"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248357669" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248357669">(Aug 04 2021 at 14:30)</a>:</h4>
<p>Im in the midst of writing an example to establish the missing context</p>



<a name="248357727"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248357727" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248357727">(Aug 04 2021 at 14:30)</a>:</h4>
<p><code>union</code> is a bad name for these types, the way they work in Rust -- IMO the right mental model here is to just think of them as convenient syntax for transmutes ("transmute whateveter the underlying bytes are to the field type"). there's no way in which a <code>union</code> is the "union" of its fields.</p>



<a name="248358298"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248358298" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248358298">(Aug 04 2021 at 14:34)</a>:</h4>
<p>just to fill in the missing context for <a href="#narrow/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety/near/248355674">my comment above</a> about codegen for <code>match</code>, here’s a <a href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=8a656a728bfa56cb4b08f8d93ce0c4e2">playground</a>, with some code like this:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">union</span> <span class="nc">U</span><span class="o">&lt;'</span><span class="na">a</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="c1">// invariant: outline.1 == 0</span>
<span class="w">    </span><span class="n">outline</span>: <span class="p">(</span><span class="o">&amp;'</span><span class="na">a</span><span class="w"> </span><span class="p">[</span><span class="kt">u32</span><span class="p">],</span><span class="w"> </span><span class="kt">u8</span><span class="p">),</span><span class="w"></span>
<span class="w">    </span><span class="c1">// invariant: inline.2 == 1</span>
<span class="w">    </span><span class="n">inline</span>: <span class="p">(</span><span class="kt">usize</span><span class="p">,</span><span class="w"> </span><span class="kt">usize</span><span class="p">,</span><span class="w"> </span><span class="kt">u8</span><span class="p">),</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>



<a name="248358337"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248358337" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248358337">(Aug 04 2021 at 14:34)</a>:</h4>
<p>and this:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="w">    </span><span class="k">unsafe</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="k">match</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">            </span><span class="n">U</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">outline</span>: <span class="p">(</span><span class="n">p</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span><span class="p">)</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="fm">println!</span><span class="p">(</span><span class="s">"outline({:?})"</span><span class="p">,</span><span class="w"> </span><span class="n">p</span><span class="p">);</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
<span class="w">            </span><span class="n">U</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">inline</span>: <span class="p">(</span><span class="n">d1</span><span class="p">,</span><span class="w"> </span><span class="n">d2</span><span class="p">,</span><span class="w"> </span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="fm">println!</span><span class="p">(</span><span class="s">"inline({:?}, {:?})"</span><span class="p">,</span><span class="w"> </span><span class="n">d1</span><span class="p">,</span><span class="w"> </span><span class="n">d2</span><span class="p">);</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
<span class="w">            </span><span class="n">_</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="fm">println!</span><span class="p">(</span><span class="s">"should be impossible if code is correct."</span><span class="p">);</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
<span class="w">        </span><span class="p">}</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
</code></pre></div>



<a name="248358461"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248358461" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248358461">(Aug 04 2021 at 14:35)</a>:</h4>
<p>in particular, <span class="user-mention" data-user-id="239881">@Josh Triplett</span> asserted during the meeting that the intention has been that one should be able to use <code>match</code> on (parts of) union fields to discriminate which field we are in.</p>



<a name="248358501"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248358501" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248358501">(Aug 04 2021 at 14:35)</a>:</h4>
<p>(as opposed to requiring that such tagging live outside the union)</p>



<a name="248358661"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248358661" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248358661">(Aug 04 2021 at 14:37)</a>:</h4>
<p><span class="user-mention" data-user-id="120791">@RalfJ</span>  I don't see a value to programmers if <code>union{u32,f32}</code>, which can only have a <code>u32</code> or <code>f32</code> written to it by fully safe code, is not readable safely from either field.</p>



<a name="248358786"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248358786" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248358786">(Aug 04 2021 at 14:37)</a>:</h4>
<p><span class="user-mention silent" data-user-id="116083">pnkfelix</span> <a href="#narrow/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety/near/248358461">said</a>:</p>
<blockquote>
<p>in particular, <span class="user-mention silent" data-user-id="239881">Josh Triplett</span> asserted during the meeting that the intention has been that one should be able to use <code>match</code> on (parts of) union fields to discriminate which field we are in.</p>
</blockquote>
<p>Now what I’m worried about is how to do codegen for something like this:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="w">    </span><span class="k">unsafe</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="k">match</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">            </span><span class="n">U</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">outline</span>: <span class="p">(</span><span class="o">&amp;</span><span class="p">[</span><span class="mi">10</span><span class="p">,</span><span class="w"> </span><span class="mi">20</span><span class="p">,</span><span class="w"> </span><span class="mi">30</span><span class="p">,</span><span class="w"> </span><span class="n">x</span><span class="p">],</span><span class="w"> </span><span class="mi">0</span><span class="p">)</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="fm">println!</span><span class="p">(</span><span class="s">"outline(... {:?})"</span><span class="p">,</span><span class="w"> </span><span class="n">x</span><span class="p">);</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
<span class="w">            </span><span class="n">U</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">inline</span>: <span class="p">(</span><span class="n">d1</span><span class="p">,</span><span class="w"> </span><span class="n">d2</span><span class="p">,</span><span class="w"> </span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="fm">println!</span><span class="p">(</span><span class="s">"inline({:?}, {:?})"</span><span class="p">,</span><span class="w"> </span><span class="n">d1</span><span class="p">,</span><span class="w"> </span><span class="n">d2</span><span class="p">);</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
<span class="w">            </span><span class="n">_</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="fm">println!</span><span class="p">(</span><span class="s">"should be impossible if code is correct."</span><span class="p">);</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
<span class="w">        </span><span class="p">}</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
</code></pre></div>



<a name="248359068"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248359068" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248359068">(Aug 04 2021 at 14:39)</a>:</h4>
<p>Handling the above requires dereferencing the <code>&amp;[u32]</code> in the <code>outline</code> case. Knowing that we are in the outline case requires inspecting the appropriate constant value (<code>0</code> in this case). But the compiler cannot be expected to infer which part of the union field has that role.</p>



<a name="248359123"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248359123" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248359123">(Aug 04 2021 at 14:39)</a>:</h4>
<p>So it seems like we may be forced to say “you cannot write code like that."</p>



<a name="248359293"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248359293" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248359293">(Aug 04 2021 at 14:40)</a>:</h4>
<p>On the plus side, Miri does detect an incorrect access from code like the above</p>



<a name="248359450"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248359450" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248359450">(Aug 04 2021 at 14:41)</a>:</h4>
<p>(i’m now checking if moving the tag to the <code>.0</code> part of each field lets the whole shebang proceed, at least in miri)</p>



<a name="248360431"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248360431" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248360431">(Aug 04 2021 at 14:48)</a>:</h4>
<p>okay, <a href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=adf95a812704901dfbecfa1032f9f0fb">confirmed</a> that putting tag data first makes miri happy. So maybe the best answer in the end is to specify that code-emission for pattern matching is specified as top-down, left-to-right, and that any deviation from that from within the compiler has to justified via static analysis.</p>



<a name="248361249"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248361249" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248361249">(Aug 04 2021 at 14:54)</a>:</h4>
<p>(and if you are forced to declare your data in an manner that makes left-to-right matching incorrect, like my <code>U { outline: … }</code> example above, then you need to force the operations to be in a valid order e.g. via guards on the arm as in <code>match u { U { outline: (p, 0) } if let &amp;[10, 20, 30, x] = p =&gt; { … } … }</code>, once if let guards are supported, that is.)</p>



<a name="248368383"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248368383" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248368383">(Aug 04 2021 at 15:46)</a>:</h4>
<p><span class="user-mention" data-user-id="120791">@RalfJ</span> The name "union" applies because it's a union of the <em>types</em> and <em>fields</em> involved, and thus also the possible values.</p>



<a name="248368892"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248368892" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248368892">(Aug 04 2021 at 15:50)</a>:</h4>
<p><span class="user-mention" data-user-id="120791">@RalfJ</span> And, sidestepping the "uninitialized memory" argument, I'm not (today) talking about MaybeUninit::uninit().assume_init(). Unions track whether they've been initialized, just like a normal let does. A union of u32 and f32 that <em>has</em> been initialized should be safe to read via either field, for the same reason that a struct with a u32 field should be safe to read the field from.</p>



<a name="248368972"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248368972" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248368972">(Aug 04 2021 at 15:51)</a>:</h4>
<p>If you assume_init on something uninitialized, the UB would happen at that point, and that's within unsafe code.</p>



<a name="248369115"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248369115" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248369115">(Aug 04 2021 at 15:52)</a>:</h4>
<p>If we make it safe to read and write both fields of a union of u32 and f32, I don't see any path by which that would allow UB in safe code.</p>



<a name="248369176"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248369176" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248369176">(Aug 04 2021 at 15:53)</a>:</h4>
<blockquote>
<p>A union of u32 and f32 that has been initialized should be safe to read via either field</p>
</blockquote>
<p>But that only works because f32 and u32 have the same validity invariants, so to support this in general there would need to be a notion of "validity equality"</p>



<a name="248369261"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248369261" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248369261">(Aug 04 2021 at 15:54)</a>:</h4>
<p>Right, and that's why this needs to wait until we have the safe-transmute infrastructure in the compiler.</p>



<a name="248369369"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248369369" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248369369">(Aug 04 2021 at 15:55)</a>:</h4>
<p>is safe-transmute infrastructure independent from unsafe-checking-on-THIR?</p>



<a name="248369407"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248369407" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248369407">(Aug 04 2021 at 15:55)</a>:</h4>
<p>(As a first pass, I think the easiest case will be when all fields are the same size and don't <em>have</em> any validity invariants.)</p>



<a name="248369476"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248369476" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248369476">(Aug 04 2021 at 15:56)</a>:</h4>
<p><span class="user-mention" data-user-id="256342">@bstrie</span> As far as I know they aren't connected...</p>



<a name="248370376"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248370376" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248370376">(Aug 04 2021 at 16:02)</a>:</h4>
<p><span class="user-mention silent" data-user-id="239881">Josh Triplett</span> <a href="#narrow/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety/near/248368892">said</a>:</p>
<blockquote>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> And, sidestepping the "uninitialized memory" argument, I'm not (today) talking about MaybeUninit::uninit().assume_init(). Unions track whether they've been initialized, just like a normal let does. A union of u32 and f32 that <em>has</em> been initialized should be safe to read via either field, for the same reason that a struct with a u32 field should be safe to read the field from.</p>
</blockquote>
<p>As mentioned though, this would have to be justified either by a safety invariant or a validity invariant imposed on all <code>union</code> types.</p>



<a name="248371900"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248371900" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248371900">(Aug 04 2021 at 16:15)</a>:</h4>
<p>I don't understand why it's imposed on all union types</p>



<a name="248372191"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248372191" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248372191">(Aug 04 2021 at 16:17)</a>:</h4>
<p>This would only apply to unions that have fields that are compatible</p>



<a name="248372660"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248372660" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248372660">(Aug 04 2021 at 16:21)</a>:</h4>
<p>Well, it seems counterintuitive that the invariant for <code>union {x: char, y: u32}</code> is more relaxed than <code>union {x: f32, y:u32}</code></p>



<a name="248372935"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248372935" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248372935">(Aug 04 2021 at 16:23)</a>:</h4>
<p><span class="user-mention" data-user-id="257758">@Connor Horman</span> What do you mean by "more relaxed"? The latter would allow safe reads, the former would not.</p>



<a name="248373131"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248373131" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248373131">(Aug 04 2021 at 16:24)</a>:</h4>
<p>Well, if we accept that as a validity invariant <code>union</code>s can be uninitialized, but unions with only compatible fields have a safety invariant that the memory must be valid for at least one of the fields, then the former can be left uninitialized and passed into foreign safe code, whereas the latter cannot.</p>



<a name="248373239"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248373239" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248373239">(Aug 04 2021 at 16:25)</a>:</h4>
<p>What do you mean by "unions can be uninitialized"?</p>



<a name="248373260"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248373260" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248373260">(Aug 04 2021 at 16:25)</a>:</h4>
<p>Not any more or less so than other types...</p>



<a name="248373485"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248373485" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248373485">(Aug 04 2021 at 16:27)</a>:</h4>
<p>There's a validity invariant that unions may contain any bit pattern, so there would be a difference for unions containing fields with types for which not all bit patterns are valid, but reading from such a field wouldn't be safe.</p>



<a name="248373725"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248373725" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248373725">(Aug 04 2021 at 16:29)</a>:</h4>
<p>You can't ever actually read uninit, i think we all agree on that.</p>
<p>thus, saying that you can read from some types of unions based on static info about the fields isn't adding any rules, because if the bytes were uninit you already weren't allowed to actually read them.</p>



<a name="248374146"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248374146" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248374146">(Aug 04 2021 at 16:32)</a>:</h4>
<blockquote>
<p>You can't ever actually read uninit, i think we all agree on that.</p>
</blockquote>
<p>"agree" is a strong word. I'm just not rehashing a well-trodden argument on that topic, because it isn't relevant to this issue about when union fields can be safe.</p>
<blockquote>
<p>thus, saying that you can read from some types of unions based on static info about the fields isn't adding any rules, because if the bytes were uninit you already weren't allowed to actually read them.</p>
</blockquote>
<p>Exactly.</p>



<a name="248375378"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248375378" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248375378">(Aug 04 2021 at 16:42)</a>:</h4>
<p><span class="user-mention silent" data-user-id="239881">Josh Triplett</span> <a href="#narrow/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety/near/248373239">said</a>:</p>
<blockquote>
<p>What do you mean by "unions can be uninitialized"?</p>
</blockquote>
<p>I agree with Connor here. I think it would be problematic to have a rule that causes <code>union { [u8; N], [u8; 8] }</code> to be valid for uninitialized memory (that is, <code>uninit().assume_init()</code> does not cause UB) for all <code>N</code> except <code>N = 8</code></p>



<a name="248375633"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248375633" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248375633">(Aug 04 2021 at 16:44)</a>:</h4>
<p>The advantage of <code>Transmutable&lt;A, B&gt;</code> is that you are explicitly opting in to the valid-A-or-B behavior, and it's a safety invariant so the compiler doesn't have to get involved</p>



<a name="248375881"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248375881" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248375881">(Aug 04 2021 at 16:46)</a>:</h4>
<p>I don't think this would change the validity invariant, just the safety invariant essentially</p>



<a name="248375909"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248375909" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248375909">(Aug 04 2021 at 16:47)</a>:</h4>
<p><span class="user-mention silent" data-user-id="224471">Lokathor</span> <a href="#narrow/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety/near/248373725">said</a>:</p>
<blockquote>
<p>You can't ever actually read uninit, i think we all agree on that.</p>
</blockquote>
<p>Actually, you can read uninit into types that allow uninit (like <code>union</code>!) That is, with the current bag-of-bytes semantics, the compiler could conceivably make reading the <code>u</code> field of <code>union { a: A, u: union { b: B, c: C } }</code> safe, although from a language consistency POV I don't think it's worth it</p>



<a name="248376448"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248376448" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248376448">(Aug 04 2021 at 16:51)</a>:</h4>
<p>I would <em>like</em> to make that safe and well-defined, but that's a problem for another day, and I don't think it's a prerequisite to making the simple case of u32/f32 unions safe.</p>



<a name="248376599"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248376599" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248376599">(Aug 04 2021 at 16:52)</a>:</h4>
<p>why can't this wait for safe-transmute? I assume that's the main reason for wanting safe unions like this</p>



<a name="248376607"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248376607" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248376607">(Aug 04 2021 at 16:52)</a>:</h4>
<p>(also, if we need to say that generic unions are only safe if they're statically provable to be safe pre-monomorphization, that seems fine. So, for instance, if you had to declare a bound using one of the safe transmute traits.)</p>



<a name="248376625"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248376625" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248376625">(Aug 04 2021 at 16:52)</a>:</h4>
<p>It can, and it should.</p>



<a name="248376647"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248376647" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248376647">(Aug 04 2021 at 16:52)</a>:</h4>
<p>It seems like safe-transmute solves these problems already and better. I don't think <code>union</code> should be used for this purpose</p>



<a name="248376673"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248376673" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248376673">(Aug 04 2021 at 16:53)</a>:</h4>
<p>I am specifically suggesting that once the safe transmute infrastructure exists in the compiler, we should use exactly the same infrastructure to determine when reading and writing union fields can be safe.</p>



<a name="248376716"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248376716" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248376716">(Aug 04 2021 at 16:53)</a>:</h4>
<p>I think it solves these problems, and I think sometimes you want a transmute and sometimes you want a union.</p>



<a name="248376816"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248376816" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248376816">(Aug 04 2021 at 16:54)</a>:</h4>
<p>because it gets really hairy to determine that all fields are layout compatible and don't have issues like <a href="#narrow/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety/near/248355544">this one</a></p>



<a name="248376928"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248376928" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248376928">(Aug 04 2021 at 16:55)</a>:</h4>
<p>That sounds like exactly the same problem the safe transmute infrastructure has: it also has to determine if (bool, u8) and (u8, bool) are compatible, which they aren't.</p>



<a name="248376935"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248376935" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248376935">(Aug 04 2021 at 16:55)</a>:</h4>
<p>Also I'm not sure that layout compatibility in the sense of safe-transmute is good enough because you can use field writes to do "recombination"</p>



<a name="248377062"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248377062" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248377062">(Aug 04 2021 at 16:56)</a>:</h4>
<p>if you construct something that is half-A and half-B it might not be valid for either one</p>



<a name="248377071"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248377071" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248377071">(Aug 04 2021 at 16:56)</a>:</h4>
<p><span class="user-mention silent" data-user-id="271719">Mario Carneiro</span> <a href="#narrow/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety/near/248376599">said</a>:</p>
<blockquote>
<p>why can't this wait for safe-transmute? I assume that's the main reason for wanting safe unions like this</p>
</blockquote>
<p>To be clear: The question being originally asked via <a href="https://github.com/rust-lang/rust/issues/87520">#87520</a> was “what patterns should be considered safe”, and the issue was specifically pointing out cases that are accepted today via the MIR unsafety checking that are questionable (at least when compared to the text of the original RFC for union).</p>



<a name="248377098"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248377098" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248377098">(Aug 04 2021 at 16:56)</a>:</h4>
<p>Also, for a first pass, it would suffice to allow safety only in the cases where every possible value is valid. So, it would be fine if introducing a bool or enum or char or any other type with some invalid bit patterns would mean you have to use unsafe.</p>



<a name="248377103"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248377103" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248377103">(Aug 04 2021 at 16:56)</a>:</h4>
<p>So my take is that, if anything, we’re trying to figure out how to make fewer things safe, not how to make more things safe.</p>



<a name="248377154"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248377154" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248377154">(Aug 04 2021 at 16:57)</a>:</h4>
<p>(Agreed. Making more things safe can happen later, when we have the safe transmit infrastructure.)</p>



<a name="248377384"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248377384" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248377384">(Aug 04 2021 at 16:58)</a>:</h4>
<p><span class="user-mention silent" data-user-id="239881">Josh Triplett</span> <a href="#narrow/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety/near/248376928">said</a>:</p>
<blockquote>
<p>That sounds like exactly the same problem the safe transmute infrastructure has: it also has to determine if (bool, u8) and (u8, bool) are compatible, which they aren't.</p>
</blockquote>
<p>(you should take a look at the example that <span class="user-mention" data-user-id="271719">@Mario Carneiro</span> and I were talking about <a href="#narrow/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety/near/248355544">above</a>. It does not strike me as the same problem as safe transmute.)</p>



<a name="248377467"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248377467" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248377467">(Aug 04 2021 at 16:59)</a>:</h4>
<p>The case of matching on a repr(u8) "zst" is interesting. I see why it is allowed to be safe, since there isn't any code run to access the union. It's not even that it would be UB for it to be anything else, it's that it is literally an irrefutable match: if you check that the value is 0 then that implies that there is another branch if it's not</p>



<a name="248377499"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248377499" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248377499">(Aug 04 2021 at 16:59)</a>:</h4>
<p>I did see that example. I was suggesting that since safe-transmute would flag those two as not compatible, all the field accesses would become unsafe, which would solve the problem.</p>



<a name="248377604"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248377604" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248377604">(Aug 04 2021 at 17:00)</a>:</h4>
<p>I see</p>



<a name="248377629"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248377629" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248377629">(Aug 04 2021 at 17:00)</a>:</h4>
<p><span class="user-mention" data-user-id="271719">@Mario Carneiro</span> Yeah, I can see why it works as well. But it also seems like confusing semantics to have anywhere near unsafe code, and it might lead people to make invalid assumptions.</p>



<a name="248377708"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248377708" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248377708">(Aug 04 2021 at 17:00)</a>:</h4>
<p><span class="user-mention" data-user-id="116083">@pnkfelix</span> To use a similar example, if you had a union of <code>(bool, u8)</code> and <code>(bool, i8)</code>, that could allow safe reads/writes.</p>



<a name="248377718"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248377718" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248377718">(Aug 04 2021 at 17:01)</a>:</h4>
<p>IMO it's not clear that even unsafe field access is enough to make enum matches viable (i.e., what the author needs to do to justify it's actually not UB)</p>



<a name="248377793"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248377793" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248377793">(Aug 04 2021 at 17:01)</a>:</h4>
<p>It is also possible to make this unsafe "by fiat", even though the desugaring doesn't say anything about this being a problem - just add a fake MIR operation to retain the fact that a union is getting matched on</p>



<a name="248377834"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248377834" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248377834">(Aug 04 2021 at 17:01)</a>:</h4>
<p><span class="user-mention" data-user-id="116122">@simulacrum</span> what do you think of my assertion <a href="#narrow/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety/near/248358786">above</a> that the only realistic plan would be to specific the pattern-match order-of-evaluation?</p>



<a name="248377957"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248377957" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248377957">(Aug 04 2021 at 17:02)</a>:</h4>
<p>I think that would <em>help</em> but it feels like the sort of thing where if I was reviewing the code I'd probably say "don't use match here", too dangerous. ifs and such are likely easier to understand, would be my guess.</p>



<a name="248378012"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248378012" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248378012">(Aug 04 2021 at 17:03)</a>:</h4>
<p>yes, I agree that I would recommend people not use <code>match</code> for such cases</p>



<a name="248378030"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248378030" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248378030">(Aug 04 2021 at 17:03)</a>:</h4>
<p>but I still think we need to spell out the compiler’s rules</p>



<a name="248378083"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248378083" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248378083">(Aug 04 2021 at 17:03)</a>:</h4>
<p>hm, I mean, the alternative is to just not support unsafe field access in matches, right?</p>



<a name="248378186"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248378186" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248378186">(Aug 04 2021 at 17:04)</a>:</h4>
<p>pattern evaluation order might also become relevant for deref-patterns</p>



<a name="248378251"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248378251" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248378251">(Aug 04 2021 at 17:05)</a>:</h4>
<p>like, I'd rather not bend over backwards to define something that restricts the compiler's implementation and is likely impractical for users to rely on, if that makes sense</p>



<a name="248378296"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248378296" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248378296">(Aug 04 2021 at 17:05)</a>:</h4>
<p>but specifying pattern evaluation order too much prevents the compiler from optimizing matches</p>



<a name="248378305"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248378305" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248378305">(Aug 04 2021 at 17:05)</a>:</h4>
<p><span class="user-mention silent" data-user-id="116083">pnkfelix</span> <a href="#narrow/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety/near/248377834">said</a>:</p>
<blockquote>
<p><span class="user-mention silent" data-user-id="116122">simulacrum</span> what do you think of my assertion <a href="#narrow/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety/near/248358786">above</a> that the only realistic plan would be to specific the pattern-match order-of-evaluation?</p>
</blockquote>
<p>I think it would be possible to do this without restricting order-of-evaluation, though it'd be a challenge.</p>



<a name="248378330"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248378330" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248378330">(Aug 04 2021 at 17:05)</a>:</h4>
<p><span class="user-mention" data-user-id="239881">@Josh Triplett</span> I don’t see how, not in the general case</p>



<a name="248378428"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248378428" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248378428">(Aug 04 2021 at 17:06)</a>:</h4>
<p><span class="user-mention" data-user-id="116083">@pnkfelix</span> You could freeze the union's memory before matching on it.</p>



<a name="248378459"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248378459" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248378459">(Aug 04 2021 at 17:06)</a>:</h4>
<p>(need to go to lang meeting, more later)</p>



<a name="248378492"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248378492" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248378492">(Aug 04 2021 at 17:06)</a>:</h4>
<p>you could do it the same way as layout optimizations: the compiler picks <em>a</em> choice and it's not UB if you guess right but the specific order is unstable</p>



<a name="248378526"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248378526" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248378526">(Aug 04 2021 at 17:07)</a>:</h4>
<p>which in practice means that you can't write matches like that</p>



<a name="248378544"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248378544" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248378544">(Aug 04 2021 at 17:07)</a>:</h4>
<p>yeah I don’t see how that’s a solution</p>



<a name="248378553"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248378553" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248378553">(Aug 04 2021 at 17:07)</a>:</h4>
<p>unless you know the order doesn't matter</p>



<a name="248378607"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248378607" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248378607">(Aug 04 2021 at 17:07)</a>:</h4>
<p>I think the alternative is if we had a "untyped" memcmp of some kind, but my understanding that's not really a thing</p>



<a name="248378689"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248378689" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248378689">(Aug 04 2021 at 17:08)</a>:</h4>
<p>(This is sort of "freeze on steroids")</p>



<a name="248378692"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248378692" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248378692">(Aug 04 2021 at 17:08)</a>:</h4>
<p>wait, memcmp is typed?</p>



<a name="248378805"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248378805" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248378805">(Aug 04 2021 at 17:09)</a>:</h4>
<p>Well, not literally memcmp, but, like, if we could lower match (maybe just for unions) to a memcmp (and that worked for uninit etc) then it might work out</p>



<a name="248380914"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248380914" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248380914">(Aug 04 2021 at 17:25)</a>:</h4>
<p><span class="user-mention" data-user-id="116122">@simulacrum</span> maybe I’m missing something, but: As I tried to illustrate <a href="#narrow/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety/near/248358786">above</a>, in general you’ll still need to handle dereferencing pointers while pattern matching. I don’t see how memcmp handles that, (unless you’re talking about something where we try to dynamically detect whether a memory address is valid to dereference?)</p>



<a name="248381125"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248381125" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248381125">(Aug 04 2021 at 17:27)</a>:</h4>
<p>Ah, sure, yes, that's still a problem. I mean that memcmp or similar may help solve the <em>flat</em> case at least, and in theory you could build some sort of rules like matching the sort of "top-level" bits that are present without going through pointers, and those dictating which pointers are (assumed) valid to follow</p>



<a name="248381175"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248381175" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248381175">(Aug 04 2021 at 17:27)</a>:</h4>
<p>Interesting. In the limiting case, you could have two pointer fields, and you need to deference one to determine the validity of the other. Matching both of those in one match arm does seem like it'd be near-impossible to support reasonably.</p>



<a name="248381290"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248381290" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248381290">(Aug 04 2021 at 17:28)</a>:</h4>
<p>talk about pathological examples, josh! what a monster</p>



<a name="248381335"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248381335" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248381335">(Aug 04 2021 at 17:29)</a>:</h4>
<p>Not completely pathological. Consider if the first is a string giving the type of the second. :)</p>



<a name="248381362"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248381362" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248381362">(Aug 04 2021 at 17:29)</a>:</h4>
<p>I am curious whether we could get way with specifying left-to-right <em>solely</em> within <code>union</code></p>



<a name="248381416"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248381416" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248381416">(Aug 04 2021 at 17:29)</a>:</h4>
<p>well it's not "in" the union, it's in the tuple match after the union</p>



<a name="248381451"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248381451" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248381451">(Aug 04 2021 at 17:29)</a>:</h4>
<p>i.e. give compiler more freedom with portions of data structures outside of the context of a <code>union</code></p>



<a name="248381522"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248381522" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248381522">(Aug 04 2021 at 17:30)</a>:</h4>
<p>Sure, I’m just saying: it could be a context-sensitive rule</p>



<a name="248381537"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248381537" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248381537">(Aug 04 2021 at 17:30)</a>:</h4>
<p><span class="user-mention" data-user-id="116083">@pnkfelix</span> I would ideally not want to prevent the compiler from doing some kind of wider comparison, if there's no padding that it needs to avoid matching (or if it has some wide comparison op that can skip the padding).</p>



<a name="248381620"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248381620" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248381620">(Aug 04 2021 at 17:30)</a>:</h4>
<p>sorry, josh, can you spell out your concern a bit more?</p>



<a name="248381657"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248381657" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248381657">(Aug 04 2021 at 17:31)</a>:</h4>
<p>are you talking about wanting to skip padding that is embedded in a union?</p>



<a name="248381702"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248381702" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248381702">(Aug 04 2021 at 17:31)</a>:</h4>
<p>I was just thinking that <code>unsafe match</code> should be a thing, so that you can say that a pattern match is doing unsafe things without also saying the same about the branches, but it occurs to me that this would also help here, since you could say that <code>unsafe match</code> has stricter ordering rules</p>



<a name="248381703"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248381703" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248381703">(Aug 04 2021 at 17:31)</a>:</h4>
<p>Ignore the padding case for now (it could be handled but it's more complex). Here's the case I'm thinking of:</p>



<a name="248381809"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248381809" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248381809">(Aug 04 2021 at 17:32)</a>:</h4>
<p><span class="user-mention silent" data-user-id="271719">Mario Carneiro</span> <a href="#narrow/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety/near/248381702">said</a>:</p>
<blockquote>
<p>I was just thinking that <code>unsafe match</code> should be a thing, so that you can say that a pattern match is doing unsafe things without also saying the same about the branches, but it occurs to me that this would also help here, since you could say that <code>unsafe match</code> has stricter ordering rules</p>
</blockquote>
<p>We've talked in the past about having "unsafe" in patterns, so you could write something like <code>match expr { unsafe { pat } =&gt; ... }</code></p>



<a name="248381932"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248381932" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248381932">(Aug 04 2021 at 17:33)</a>:</h4>
<p>I suppose the idea of having <code>unsafe</code> imply stricter order-of-eval for patterns works for both <code>unsafe match</code> and <code>unsafe { pat }</code></p>



<a name="248381959"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248381959" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248381959">(Aug 04 2021 at 17:33)</a>:</h4>
<p>If I have <code>union U { n: u32, f: f32 }; struct S { ty: u32, val: U }</code>, and I write a match arm <code>S { ty: 0, val: U { n: 42 } }</code>, it <em>should</em> be fine to match the whole 64 bits at a time.</p>



<a name="248382061"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248382061" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248382061">(Aug 04 2021 at 17:34)</a>:</h4>
<p>...unsafely?</p>



<a name="248382096"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248382096" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248382096">(Aug 04 2021 at 17:34)</a>:</h4>
<p>Safely, but that's orthogonal to the point; I'm suggesting that strict "left-to-right" semantics might not allow that.</p>



<a name="248382114"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248382114" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248382114">(Aug 04 2021 at 17:34)</a>:</h4>
<p>And I think we shouldn't prevent the compiler from emitting that code.</p>



<a name="248382159"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248382159" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248382159">(Aug 04 2021 at 17:35)</a>:</h4>
<p>that sounds like it could be implemented as a compiler optimization based on the type definitions</p>



<a name="248382230"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248382230" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248382230">(Aug 04 2021 at 17:35)</a>:</h4>
<p>Or at least, I do not yet see where order-of-eval breaks that specific case. Unless you meant that the compiler has to assume there might be padding in there, even when it knows there isn’t?</p>



<a name="248382309"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248382309" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248382309">(Aug 04 2021 at 17:36)</a>:</h4>
<p>If you are okay with having this be a "spurious unsafe", I don't see any problem with that code - presumably you know that your union is initialized and there aren't any pointers to cause issues, so as a user you should feel fine writing that, and the compiler is under no particular obligations</p>



<a name="248382328"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248382328" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248382328">(Aug 04 2021 at 17:36)</a>:</h4>
<p><span class="user-mention" data-user-id="116083">@pnkfelix</span> I see. You're suggesting that the compiler could see that the types are all valid-for-all-bit-patterns and then use the as-if rule to do a 64-bit match?</p>



<a name="248382361"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248382361" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248382361">(Aug 04 2021 at 17:36)</a>:</h4>
<p>I guess your point is that if the semantics is that we never inspect <code>U { n: … }</code> as a pattern without separately checking the <code>ty == 0</code> , then that is what breaks reading all 64-bits at once?</p>



<a name="248382383"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248382383" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248382383">(Aug 04 2021 at 17:36)</a>:</h4>
<p><span class="user-mention silent" data-user-id="239881">Josh Triplett</span> <a href="#narrow/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety/near/248382328">said</a>:</p>
<blockquote>
<p><span class="user-mention silent" data-user-id="116083">pnkfelix</span> I see. You're suggesting that the compiler could see that the types are all valid-for-all-bit-patterns and then use the as-if rule to do a 64-bit match?</p>
</blockquote>
<p>yes, that is essentially what I was getting at</p>



<a name="248382419"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248382419" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248382419">(Aug 04 2021 at 17:37)</a>:</h4>
<p><span class="user-mention" data-user-id="116083">@pnkfelix</span> Right, exactly. I don't want the way in which we specify the semantics to <em>prevent</em> the compiler from doing that optimization when it can.</p>



<a name="248382438"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248382438" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248382438">(Aug 04 2021 at 17:37)</a>:</h4>
<p>because I can imagine variations of your example, namely involving pointers, where it would absolutely be wrong to try to deref the pointer without first separately confirming the type-tag</p>



<a name="248382453"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248382453" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248382453">(Aug 04 2021 at 17:37)</a>:</h4>
<p><span class="user-mention" data-user-id="116083">@pnkfelix</span> <em>Absolutely</em>!</p>



<a name="248382582"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248382582" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248382582">(Aug 04 2021 at 17:38)</a>:</h4>
<p>If one of the union variants were a pointer-to-string, you couldn't dereference and do a string comparison before you check the ty field.</p>



<a name="248382605"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248382605" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248382605">(Aug 04 2021 at 17:38)</a>:</h4>
<p>What if the other variant is <code>()</code>?</p>



<a name="248382637"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248382637" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248382637">(Aug 04 2021 at 17:39)</a>:</h4>
<p><span class="user-mention" data-user-id="271719">@Mario Carneiro</span> Then the match should be <em>unsafe</em>, but the compiler could still theoretically do a 64-bit comparison.</p>



<a name="248382681"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248382681" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248382681">(Aug 04 2021 at 17:39)</a>:</h4>
<p>For me, I’m more concerned about whether we want to allow <code>U { n: usize, p: &amp;’static Thing }; struct S { ty: u32, val: U }</code> and a subsequent match arm <code>S { val: U { p: &amp;Thing(UH_OH) }, ty: THING_TAG }</code></p>



<a name="248382710"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248382710" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248382710">(Aug 04 2021 at 17:39)</a>:</h4>
<p>Is it safe to do a 64-bit comparison with a partially uninitialized value (in LLVM)?</p>



<a name="248382792"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248382792" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248382792">(Aug 04 2021 at 17:40)</a>:</h4>
<p><span class="user-mention" data-user-id="271719">@Mario Carneiro</span> That's why I was suggesting that one solution would be for the match to emit a <code>freeze</code> operation on the union's memory before doing a comparison.</p>



<a name="248382806"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248382806" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248382806">(Aug 04 2021 at 17:40)</a>:</h4>
<p>or if the match arm, as written by the user, has to <em>always</em> put the <code>ty</code> to the left of the <code>val</code> in the struct pattern</p>



<a name="248382821"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248382821" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248382821">(Aug 04 2021 at 17:40)</a>:</h4>
<p><span class="user-mention silent" data-user-id="116083">pnkfelix</span> <a href="#narrow/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety/near/248382681">said</a>:</p>
<blockquote>
<p>For me, I’m more concerned about whether we want to allow <code>U { n: usize, p: &amp;’static Thing }; struct S { ty: u32, val: U }</code> and a subsequent match arm <code>S { val: U { p: &amp;Thing(UH_OH) }, ty: THING_TAG }</code></p>
</blockquote>
<p>That's an <em>excellent</em> question.</p>



<a name="248382889"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248382889" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248382889">(Aug 04 2021 at 17:41)</a>:</h4>
<p>I suppose that might be a case where people will be advised to prefer tuple-structs over named-fields</p>



<a name="248382919"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248382919" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248382919">(Aug 04 2021 at 17:41)</a>:</h4>
<p>in order to encourage specific pattern-evaluation orderings</p>



<a name="248383005"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248383005" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248383005">(Aug 04 2021 at 17:42)</a>:</h4>
<p>this all seems very footgunny</p>



<a name="248383050"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248383050" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248383050">(Aug 04 2021 at 17:42)</a>:</h4>
<p>I'm not sure <code>unsafe</code> is even good enough to cover this</p>



<a name="248383089"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248383089" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248383089">(Aug 04 2021 at 17:43)</a>:</h4>
<p>because people will already be expecting to have to use <code>unsafe</code> around unions</p>



<a name="248383129"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248383129" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248383129">(Aug 04 2021 at 17:43)</a>:</h4>
<p>I do think it's important to allow matching a type tag and the associated value in the same match arm. But I can <em>definitely</em> imagine that there are corner cases of that that we can't support.</p>



<a name="248383227"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248383227" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248383227">(Aug 04 2021 at 17:44)</a>:</h4>
<p><span class="user-mention silent" data-user-id="116083">pnkfelix</span> <a href="#narrow/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety/near/248382889">said</a>:</p>
<blockquote>
<p>I suppose that might be a case where people will be advised to prefer tuple-structs over named-fields</p>
</blockquote>
<p>(even though one could still write <code>{S { 1: U { p: &amp;Thing(UH_OH) }, 0: THING_TAG }</code>)</p>



<a name="248383243"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248383243" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248383243">(Aug 04 2021 at 17:44)</a>:</h4>
<p>I think the reference case would be sufficiently complicated to support that for the moment we probably <em>don't</em> want to support that.</p>



<a name="248383305"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248383305" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248383305">(Aug 04 2021 at 17:45)</a>:</h4>
<p>What does “don’t want to” mean here? I.e., some cases of this work today</p>



<a name="248383335"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248383335" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248383335">(Aug 04 2021 at 17:45)</a>:</h4>
<p>namely, Miri accepts code that obeys the left-to-right ordering rule</p>



<a name="248383354"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248383354" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248383354">(Aug 04 2021 at 17:45)</a>:</h4>
<p><span class="user-mention silent" data-user-id="116083">pnkfelix</span> <a href="#narrow/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety/near/248383335">said</a>:</p>
<blockquote>
<p>namely, Miri accepts code that obeys the left-to-right ordering rule</p>
</blockquote>
<p>I didn't know that rule was part of the compiler's semantics today...</p>



<a name="248383362"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248383362" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248383362">(Aug 04 2021 at 17:45)</a>:</h4>
<p>(from what I’ve seen so far, that is. I admit its been a shallow investigation.)</p>



<a name="248383366"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248383366" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248383366">(Aug 04 2021 at 17:45)</a>:</h4>
<p>I thought that was a proposed semantics.</p>



<a name="248383445"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248383445" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248383445">(Aug 04 2021 at 17:46)</a>:</h4>
<p>right, and I’m trying to figure out what we’re willing to specify as “will work in the future"</p>



<a name="248383496"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248383496" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248383496">(Aug 04 2021 at 17:46)</a>:</h4>
<p>if we’re talking about invalidating <em>all</em> cases where a match pattern dereferences under a union, then that is a breaking change from today</p>



<a name="248383516"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248383516" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248383516">(Aug 04 2021 at 17:46)</a>:</h4>
<p>/me shakes his head.</p>



<a name="248383541"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248383541" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248383541">(Aug 04 2021 at 17:47)</a>:</h4>
<p>At most, we'd be talking about cases of matching a reference while simultaneously determining if that reference is valid.</p>



<a name="248383569"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248383569" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248383569">(Aug 04 2021 at 17:47)</a>:</h4>
<p>But if we already specify left-to-right, that could potentially work.</p>



<a name="248383614"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248383614" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248383614">(Aug 04 2021 at 17:47)</a>:</h4>
<p>right now my guess is that the compiler is doing mostly left to right ordering during MIR generation since that's the obvious thing to do, and the soundness of the operations is well defined by that point</p>



<a name="248383686"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248383686" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248383686">(Aug 04 2021 at 17:48)</a>:</h4>
<p>Its tough because I don’t know what we actually <em>specify</em> today. Its hard for users to observe the ordering. (Maybe impossible, at least in stable code, becase we don’t support <code>Deref</code> in patterns?)</p>



<a name="248383687"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248383687" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248383687">(Aug 04 2021 at 17:48)</a>:</h4>
<p>Just to confirm, I <em>think</em> the question of match order is orthogonal to unsafety, insofar as we need to handle match order whether a field is safe or unsafe to read?</p>



<a name="248383697"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248383697" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248383697">(Aug 04 2021 at 17:48)</a>:</h4>
<p>so it's not too surprising that miri testing reveals this</p>



<a name="248383730"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248383730" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248383730">(Aug 04 2021 at 17:48)</a>:</h4>
<p><span class="user-mention silent" data-user-id="116083">pnkfelix</span> <a href="#narrow/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety/near/248383686">said</a>:</p>
<blockquote>
<p>Its tough because I don’t know what we actually <em>specify</em> today. Its hard for users to observe the ordering. (Maybe impossible, at least in stable code, becase we don’t support <code>Deref</code> in patterns?)</p>
</blockquote>
<p>Do we support user-defined Eq in patterns?</p>



<a name="248383760"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248383760" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248383760">(Aug 04 2021 at 17:49)</a>:</h4>
<p>ah, right. Matching CONST sometimes uses <code>Eq</code></p>



<a name="248383773"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248383773" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248383773">(Aug 04 2021 at 17:49)</a>:</h4>
<p>or at least it used to</p>



<a name="248383781"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248383781" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248383781">(Aug 04 2021 at 17:49)</a>:</h4>
<p>we tried to legislate that away</p>



<a name="248383797"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248383797" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248383797">(Aug 04 2021 at 17:49)</a>:</h4>
<p>I thought that's restricted to structural_eq marked impls or something?</p>



<a name="248383804"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248383804" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248383804">(Aug 04 2021 at 17:49)</a>:</h4>
<p>Doesn't that require the unstable <code>StructuralEq</code> trait?</p>



<a name="248383811"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248383811" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248383811">(Aug 04 2021 at 17:49)</a>:</h4>
<p>which now ties into the struct equality question. :)</p>



<a name="248383818"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248383818" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248383818">(Aug 04 2021 at 17:49)</a>:</h4>
<p>right right</p>



<a name="248383835"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248383835" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248383835">(Aug 04 2021 at 17:49)</a>:</h4>
<p>so users cannot override it</p>



<a name="248383851"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248383851" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248383851">(Aug 04 2021 at 17:49)</a>:</h4>
<p>it needs to be a derived implementation of <code>PartialEq</code>, all the way down</p>



<a name="248383869"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248383869" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248383869">(Aug 04 2021 at 17:49)</a>:</h4>
<p>if I recall correctly</p>



<a name="248384048"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248384048" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248384048">(Aug 04 2021 at 17:51)</a>:</h4>
<p>So: unstable code can observe order of pattern evaluation, e.g. via manual impl of <code>StructuralEq</code> and manual impl of <code>PartialEq</code>, etc.</p>



<a name="248384096"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248384096" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248384096">(Aug 04 2021 at 17:51)</a>:</h4>
<p>but still, no evidence that I know of that stable code can observe pattern order-of-eval</p>



<a name="248384196"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248384196" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248384196">(Aug 04 2021 at 17:52)</a>:</h4>
<p>I have to admit, I’m sort of amazed that the conversation took a turn that ended up aligning with the struct-eq stuff.</p>



<a name="248384580"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248384580" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248384580">(Aug 04 2021 at 17:55)</a>:</h4>
<p>So just a quick summary so far: if supporting detection of tag field and also payload field in a single match is desired, we need one of:</p>
<ul>
<li>a way to tell the compiler which field is the tag</li>
<li>a very clearly specified order for how matching works.</li>
<li>implicit freeze operation on the full union before the matching begins.</li>
</ul>



<a name="248384954"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248384954" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248384954">(Aug 04 2021 at 17:58)</a>:</h4>
<p>You also need a way to make sure all the tags in the different fields line up, which I think is difficult to impossible in repr(rust)</p>



<a name="248385321"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248385321" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248385321">(Aug 04 2021 at 18:01)</a>:</h4>
<p>could always use two unions and a struct</p>



<a name="248385384"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248385384" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248385384">(Aug 04 2021 at 18:01)</a>:</h4>
<p>I think an implicit freeze would suffice for any case that doesn't involve dereferencing a potentially invalid pointer.</p>



<a name="248385537"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248385537" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248385537">(Aug 04 2021 at 18:03)</a>:</h4>
<p>You'd need to make sure your reads are unaligned, too, I think, if you want to support variable length tags (e.g, some u8 and some u64), right?</p>



<a name="248385686"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248385686" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248385686">(Aug 04 2021 at 18:04)</a>:</h4>
<p>(I guess it depends -- maybe that's only the case if you can have an unaligned field, such as in a packed union?)</p>



<a name="248386091"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248386091" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248386091">(Aug 04 2021 at 18:07)</a>:</h4>
<p>Right, as far as I know a union with a u64 field has u64 alignment unless you do something to change that (such as packing).</p>



<a name="248603588"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248603588" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248603588">(Aug 06 2021 at 12:24)</a>:</h4>
<p><span class="user-mention silent" data-user-id="224471">Lokathor</span> <a href="#narrow/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety/near/248358661">said</a>:</p>
<blockquote>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span>  I don't see a value to programmers if <code>union{u32,f32}</code>, which can only have a <code>u32</code> or <code>f32</code> written to it by fully safe code, is not readable safely from either field.</p>
</blockquote>
<p>I think trying to capture in the validity (or safety) invariant properties such as "every field allows value X on this byte" is fragile and a lot more complicated than the benefits that could be gained from this.</p>



<a name="248603824"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248603824" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248603824">(Aug 06 2021 at 12:27)</a>:</h4>
<p><span class="user-mention silent" data-user-id="239881">Josh Triplett</span> <a href="#narrow/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety/near/248373260">said</a>:</p>
<blockquote>
<p>What do you mean by "unions can be uninitialized"?<br>
Not any more or less so than other types...</p>
</blockquote>
<p>That's not at all how my <a href="https://github.com/rust-lang/unsafe-code-guidelines/issues/73">proposed model of unions</a> works. There, all unions can always be uninitialized (and besides padding they are in fact the old types that can be uninitialized).</p>
<p>But anyway, for now we seem to all agree that all accesses should be unsafe for now (except maybe for <code>()</code>), and all potential relaxations of this can delegated to the future.</p>



<a name="248603968"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248603968" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248603968">(Aug 06 2021 at 12:29)</a>:</h4>
<p><span class="user-mention silent" data-user-id="239881">Josh Triplett</span> <a href="#narrow/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety/near/248385384">said</a>:</p>
<blockquote>
<p>I think an implicit freeze would suffice for any case that doesn't involve dereferencing a potentially invalid pointer.</p>
</blockquote>
<p>I am rather sceptical of any solution that relies on <code>freeze</code>...</p>



<a name="248617198"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248617198" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248617198">(Aug 06 2021 at 14:22)</a>:</h4>
<p>i wouldn't call it an altered validity invariant, I'd call it a safety invariant</p>



<a name="248617344"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248617344" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248617344">(Aug 06 2021 at 14:24)</a>:</h4>
<p>Same as you can make &amp;str values not contain valid utf8 using unsafe, but it's absolutely the fault of the unsafe code that made that value and let it out into the rest of the program when things go wrong.</p>



<a name="248618277"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248618277" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248618277">(Aug 06 2021 at 14:31)</a>:</h4>
<p><span class="user-mention silent" data-user-id="224471">Lokathor</span> <a href="#narrow/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety/near/248617198">said</a>:</p>
<blockquote>
<p>i wouldn't call it an altered validity invariant, I'd call it a safety invariant</p>
</blockquote>
<p>yeah but <code>str</code> is a particular type that <em>we</em> define. OTOH as language designers we are not really in the business of defining the safety invariants of <em>user-defined</em> types like <code>union</code>s.</p>



<a name="248619057"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248619057" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248619057">(Aug 06 2021 at 14:38)</a>:</h4>
<p>not normally, no.</p>
<p>Then again, if you violate the safety invariant and put uninit into the union and someone goes and reads it, then that's UB anyway, even if textually on the page it said <code>unsafe { }</code>. So I don't think this is a heavy burden.</p>
<p>but hek it could be a repr modifier like align, i dont think anyone would mind. What nearly everyone wants is safe reading of an initialized union when the compiler can statically determine that it's fine.</p>



<a name="248632117"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248632117" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248632117">(Aug 06 2021 at 16:16)</a>:</h4>
<p><span class="user-mention" data-user-id="120791">@RalfJ</span> I think that interpretation of unions is a major question for discussion.</p>



<a name="248632262"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248632262" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248632262">(Aug 06 2021 at 16:17)</a>:</h4>
<p>There was a large discussion about union semantics at the last Rust all-hands, the outcome of which did settle one question: unions are a bag of bits that may have any value, including values not valid for any of the variants, and that's allowed as long as you don't read any of the variants.</p>



<a name="248632318"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248632318" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248632318">(Aug 06 2021 at 16:18)</a>:</h4>
<p><span class="user-mention silent" data-user-id="239881">Josh Triplett</span> <a href="#narrow/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety/near/248632117">said</a>:</p>
<blockquote>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> I think that interpretation of unions is a major question for discussion.</p>
</blockquote>
<p>yeah I guess so. ;) I hope to finally write down the framework that would allow us to have this discussion in a more precise way...</p>



<a name="248632442"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248632442" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248632442">(Aug 06 2021 at 16:19)</a>:</h4>
<p>That discussion at the all-hands didn't settle the issue of uninitialized unions, and I don't recall anyone at the meeting bringing up the compiler-oriented notion of "uninitialized" being different from any actual value of the bits in memory.</p>



<a name="248632650"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248632650" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248632650">(Aug 06 2021 at 16:21)</a>:</h4>
<p>But in any case, without settling that question, I think it's still reasonable to say that union field reads may be safe under some circumstances, and that shouldn't be incompatible with either answer regarding uninitialized unions, if we say that the responsibility to avoid undefined behavior lies with whoever leaves a union uninitialized and lets some other safe code think it can read from it.</p>



<a name="248632777"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248632777" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248632777">(Aug 06 2021 at 16:22)</a>:</h4>
<p>To the best of my knowledge, even if a union can be uninitialized, you can't create an uninitialized union that other code thinks is initialized (and thus thinks it can read from) without unsafe code. So we could say that that unsafe code is responsible for avoiding undefined behavior.</p>



<a name="248632795"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248632795" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248632795">(Aug 06 2021 at 16:22)</a>:</h4>
<p>Does that seem potentially reasonable?</p>



<a name="248632823"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248632823" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248632823">(Aug 06 2021 at 16:22)</a>:</h4>
<p>you are basically suggesting what <span class="user-mention" data-user-id="224471">@Lokathor</span> did, to make this a safety invariant</p>



<a name="248632869"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248632869" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248632869">(Aug 06 2021 at 16:22)</a>:</h4>
<p>I dont like putting a safety invariant on user-defined unions, but I agree that this could be done</p>



<a name="248633131"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248633131" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248633131">(Aug 06 2021 at 16:24)</a>:</h4>
<p>can safety invariants be weakened by user code? That would let you write unsound functions using only safe code, although since it's a user safety invariant this is arguably not the language's problem</p>



<a name="248633303"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248633303" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248633303">(Aug 06 2021 at 16:25)</a>:</h4>
<p>(i.e. if you wanted a bag-of-bits union and put a safety invariant that says it can be uninit, even though it is implemented with a rust <code>union</code> which has a safety invariant disallowing uninit, under Josh's proposal)</p>



<a name="248633398"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248633398" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248633398">(Aug 06 2021 at 16:26)</a>:</h4>
<p>safety invariants cannot in general be weakened because you don't know what unsafe code is relying on them to create a safe API.</p>



<a name="248633566"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248633566" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248633566">(Aug 06 2021 at 16:27)</a>:</h4>
<p>If it is a user API over a rust builtin that seems to be less of a concern - you only have to worry about things the compiler is doing, which in this case means you have to audit code not marked <code>unsafe</code> as though it was</p>



<a name="248633762"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248633762" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248633762">(Aug 06 2021 at 16:28)</a>:</h4>
<p>If you want uninit, MaybeUninit would continue to exist, and the way it's currently implemented internally in the compiler wouldn't even allow safe field reads because it's a <code>union{(),T}</code>, so saying "when fields match it becomes safe" doesn't affect that since () doesn't match with T. even if it matches with a monomorph of T because T is a ZST, that's actually still "fine" since the read is a read of 0 bytes.</p>



<a name="248633825"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248633825" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248633825">(Aug 06 2021 at 16:29)</a>:</h4>
<p>what about <code>MaybeUninit&lt;()&gt;</code>?</p>



<a name="248633923"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248633923" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248633923">(Aug 06 2021 at 16:29)</a>:</h4>
<p><span class="user-mention silent" data-user-id="271719">Mario Carneiro</span> <a href="#narrow/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety/near/248633131">said</a>:</p>
<blockquote>
<p>can safety invariants be weakened by user code? That would let you write unsound functions using only safe code, although since it's a user safety invariant this is arguably not the language's problem</p>
</blockquote>
<p>weakened compared to what?</p>



<a name="248633926"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248633926" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248633926">(Aug 06 2021 at 16:29)</a>:</h4>
<p>then what i just said applies, you can read out a () but that's fine because you're reading 0 bytes so none of the bytes read are uninit</p>



<a name="248634016"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248634016" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248634016">(Aug 06 2021 at 16:30)</a>:</h4>
<p>in principle it is possible to have a safety invariant on a private field that is weaker than what the type of the field would dictate. I'd usually advise against it though...</p>



<a name="248634074"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248634074" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248634074">(Aug 06 2021 at 16:30)</a>:</h4>
<p><span class="user-mention" data-user-id="120791">@RalfJ</span> what do you think of an opt-in repr modifier</p>



<a name="248634107"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248634107" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248634107">(Aug 06 2021 at 16:30)</a>:</h4>
<p><code>repr</code> doesnt feel like the right hammer to me</p>



<a name="248634174"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248634174" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248634174">(Aug 06 2021 at 16:31)</a>:</h4>
<p><span class="user-mention" data-user-id="120791">@RalfJ</span> For example, suppose someone made a wrapper around <code>str</code> to <code>NotUtf8</code> which acts the same as <code>[u8]</code>. As long as they expose the right API that seems like it could be done (although in this particular case it would be dumb since <code>[u8]</code> already exists)</p>



<a name="248634187"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248634187" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248634187">(Aug 06 2021 at 16:31)</a>:</h4>
<p>but yeah some kind of opt-in from the type author to make explicit this part of their safety invariant would help I think</p>



<a name="248634206"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248634206" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248634206">(Aug 06 2021 at 16:31)</a>:</h4>
<p><span class="user-mention silent" data-user-id="271719">Mario Carneiro</span> <a href="#narrow/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety/near/248634174">said</a>:</p>
<blockquote>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> For example, suppose someone made a wrapper around <code>str</code> to <code>NotUtf8</code> which acts the same as <code>[u8]</code>. As long as they expose the right API that seems like it could be done (although in this particular case it would be dumb since <code>[u8]</code> already exists)</p>
</blockquote>
<p>yes exactly</p>



<a name="248634230"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248634230" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248634230">(Aug 06 2021 at 16:31)</a>:</h4>
<p>it can be done but it's usually not a good idea</p>



<a name="248634307"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248634307" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248634307">(Aug 06 2021 at 16:32)</a>:</h4>
<p>I think the reverse is <em>much</em> better: the default should be the weak contract and a user API can put the stronger invariant on top</p>



<a name="248634325"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248634325" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248634325">(Aug 06 2021 at 16:32)</a>:</h4>
<p><code>Ref</code> and <code>RefMut</code> do this, btw... the lifetime they use on their ptr to the RefCell content is too long. And indeed this actually leads to a soundness problem...</p>



<a name="248634369"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248634369" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248634369">(Aug 06 2021 at 16:32)</a>:</h4>
<p>(<a href="https://github.com/rust-lang/rust/issues/63787">https://github.com/rust-lang/rust/issues/63787</a>)</p>



<a name="248634496"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248634496" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248634496">(Aug 06 2021 at 16:33)</a>:</h4>
<p>The <code>Transmutable&lt;A, B&gt;</code> type I mentioned does basically this for <code>union</code>: it's a union with the added safety invariant that the value is valid for one of the two types, so reads are safe</p>



<a name="248634533"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248634533" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248634533">(Aug 06 2021 at 16:33)</a>:</h4>
<p>Is the main argument against it that it lacks language sugar?</p>



<a name="248634548"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248634548" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248634548">(Aug 06 2021 at 16:34)</a>:</h4>
<p>yeah</p>



<a name="248634729"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248634729" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248634729">(Aug 06 2021 at 16:35)</a>:</h4>
<p>the point is safe union field reads. any design path that doesn't get there is thus missing the goal.</p>



<a name="248634944"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248634944" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248634944">(Aug 06 2021 at 16:36)</a>:</h4>
<p>does it have to be <code>union</code> specifically? i.e. (straw-man proposal) if there was <code>safe_union</code> that had the same syntax but acted like <code>Transmutable</code> then that would solve the problem</p>



<a name="248635100"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248635100" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248635100">(Aug 06 2021 at 16:37)</a>:</h4>
<p>an attribute could probably work (probably not <code>repr</code> since it's not changing the repr)</p>



<a name="248636694"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248636694" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Smittyvb <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248636694">(Aug 06 2021 at 16:49)</a>:</h4>
<p>With box_patterns you can safely destructure a Box in a way that looks a lot like dereferencing a null pointer: <a href="https://play.rust-lang.org/?version=nightly&amp;mode=release&amp;edition=2018&amp;gist=7d083001d68c11d606930f627b0bcd3b">https://play.rust-lang.org/?version=nightly&amp;mode=release&amp;edition=2018&amp;gist=7d083001d68c11d606930f627b0bcd3b</a></p>



<a name="248640211"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248640211" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248640211">(Aug 06 2021 at 17:14)</a>:</h4>
<p>Yeah, unions with reference fields is very dangerous indeed.</p>



<a name="248666557"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248666557" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248666557">(Aug 06 2021 at 20:48)</a>:</h4>
<p><span class="user-mention silent" data-user-id="317035">Smittyvb</span> <a href="#narrow/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety/near/248636694">said</a>:</p>
<blockquote>
<p>With box_patterns you can safely destructure a Box in a way that looks a lot like dereferencing a null pointer: <a href="https://play.rust-lang.org/?version=nightly&amp;mode=release&amp;edition=2018&amp;gist=7d083001d68c11d606930f627b0bcd3b">https://play.rust-lang.org/?version=nightly&amp;mode=release&amp;edition=2018&amp;gist=7d083001d68c11d606930f627b0bcd3b</a></p>
</blockquote>
<p>“looks a lot like”, but not doing so in actuality, at least not according to Miri. Here’s a variant (similar to something I wrote earlier in this topic) that actually <em>is</em> doing such a dereference (and Miri flags it as being UB):<a href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=a8c41f39db4143676f9140d17ca09285">https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=a8c41f39db4143676f9140d17ca09285</a></p>



<a name="248666663"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248666663" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248666663">(Aug 06 2021 at 20:49)</a>:</h4>
<p><del>oh sorry, need to update that link</del> (corrected now)</p>



<a name="248668872"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248668872" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248668872">(Aug 06 2021 at 21:10)</a>:</h4>
<p>I wonder whether to fix this issue it would suffice to say that a pattern match on a unit struct or enum with one variant counts as a read of the place, inserting a fake read if necessary.  That means that <code>let _ = *ptr;</code> is a no-op but <code>let () = *ptr;</code> "reads the pointer" and so is unsafe (although it is still a no-op)</p>



<a name="248669662"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/union%20field%20semantics%20and%20safety/near/248669662" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/union.20field.20semantics.20and.20safety.html#248669662">(Aug 06 2021 at 21:16)</a>:</h4>
<p>That sounds potentially reasonable.</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>